package com.qkl.xiatang.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qkl.xiatang.app.dto.BusinessDTO;
import com.qkl.xiatang.app.dto.device.*;
import com.qkl.xiatang.app.entity.device.*;
import com.qkl.xiatang.app.entity.pond.PondEntity;
import com.qkl.xiatang.app.mapper.*;
import com.qkl.xiatang.app.utils.AppSessionUtils;
import com.qkl.xiatang.app.utils.ErrorCodeUtils;
import com.qkl.xiatang.app.utils.appenum.SensorTypeEnum;
import com.qkl.xiatang.app.utils.appenum.SensorTypeNormalEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class DeviceManagerService {

    @Autowired
    private SensorMapper sensorMapper;

    @Autowired
    private DeviceNormalMapper deviceNormalMapper;

    @Autowired
    private DeviceNormaTemplateMapper deviceNormaTemplateMapper;

    @Autowired
    private DeviceDataMapper deviceDataMapper;

    @Autowired
    private MessageService messageService;

    @Autowired
    private SensorPondMapper sensorPondMapper;

    @Autowired
    private PondManagerMapper pondManagerMapper;

    @Autowired
    private SensorTypeSortMapper sensorTypeSortMapper;


    public List<SensorEntity> querySensorList(String companyId){
        return sensorMapper.selectList(new QueryWrapper<SensorEntity>().eq("company_id",companyId));
    }

    /**
     * 传感器设备网关查询
     * @return
     */
    public BusinessDTO<Object> querySensorList(){
        List<SensorEntity> list = this.querySensorList(AppSessionUtils.getCompanyId());
        if(ObjectUtils.isEmpty(list)){
            list = new ArrayList<>();
        }else{
            for (SensorEntity entity : list){
                if(null == deviceDataMapper.querySensorData(entity.getSn())){
                    entity.setStatus(0);
                }else{
                    entity.setStatus(1);
                }
            }
        }
        Map<String,Object> map = new HashMap<>();
        map.put("list",list);
        return BusinessDTO.sucessBusiness(map,"传感器设备网关查询");
    }

    /**
     * 传感器设备网关设置默认
     * @param sensorId 传感器设备网关id
     * @return
     */
    public BusinessDTO<Object> sensorDefault(String sensorId){
        SensorEntity queryEntity = sensorMapper.selectById(sensorId);
        String companyId = AppSessionUtils.getCompanyId();
        if( null == queryEntity || null == queryEntity.getCompanyId() || !queryEntity.getCompanyId().equals(companyId) ){
            return BusinessDTO.failBusiness("无此传感器设备网关");
        }
        SensorEntity updEntity = new SensorEntity();
        updEntity.setId(sensorId);
        updEntity.setIsDefault(1);
        sensorMapper.updateById(updEntity);

        List<SensorEntity> list = this.querySensorList(companyId);
        if(ObjectUtils.isNotEmpty(list)){
            for (SensorEntity entity : list){
                if( !sensorId.equals(entity.getId())){
                    SensorEntity sensor = new SensorEntity();
                    sensor.setId(entity.getId());
                    sensor.setIsDefault(0);
                    sensorMapper.updateById(sensor);
                }
            }
        }
        return BusinessDTO.sucessBusiness(new HashMap<>(),"传感器设备网关设置默认");
    }

    /**
     * 传感器网关数据查询
     * @param sn
     * @return
     */
    public BusinessDTO<SensorDataListOutDTO> querySensorData(String sn){
        BusinessDTO<SensorDataListOutDTO> businessDTO = this.querySensorData0(sn);
        messageService.addMessage(businessDTO);
        return businessDTO;
    }
    private BusinessDTO<SensorDataListOutDTO> querySensorData0(String sn){
        sn = StringUtils.trimToEmpty(sn);
        String companyId = AppSessionUtils.getCompanyId();
        if(StringUtils.isEmpty(sn)){
            List<SensorEntity> list = this.querySensorList(companyId);
            if(ObjectUtils.isNotEmpty(list)){
                for (SensorEntity entity : list){
                    sn = entity.getSn();
                    if(entity.defaultSensor()){
                        break;
                    }
                }
            }
        }
        if(StringUtils.isEmpty(sn)){
            return this.querySensorDataDefault();
        }
        List<SensorEntity> sensorList = sensorMapper.selectList(new QueryWrapper<SensorEntity>().eq("sn",sn).eq("company_id",companyId));
        if(ObjectUtils.isEmpty(sensorList)){
            return this.querySensorDataDefault();
        }
        SensorEntity sensorEntity = sensorList.get(0);
        String sensorType = sensorEntity.getType();
        String name = sensorEntity.getName();
        SensorDataDTO dataDTO = deviceDataMapper.querySensorData(sn);
        if(null == dataDTO){
            //return BusinessDTO.failBusiness(ErrorCodeUtils.DEVICE_NOT_LINE,ErrorCodeUtils.DEVICE_NOT_LINE_MSG);
            return this.querySensorDataDefault();
        }
        List<DeviceNormalEntity> normalEntityList = this.queryNormalList(companyId);
        if(ObjectUtils.isEmpty(normalEntityList)){
            this.initDeviceNormal(deviceNormaTemplateMapper.selectList(null),companyId);
            normalEntityList = this.queryNormalList(companyId);
        }
        if(ObjectUtils.isNotEmpty(normalEntityList)){
            for(DeviceNormalEntity normalEntity : normalEntityList){
                dataDTO.setNormal(normalEntity);
            }
        }

        List<SensorPondEntity> sensorPondList = this.querySensorPondList(companyId,sn);
        if(ObjectUtils.isNotEmpty(sensorPondList)){
            List<String> pondNameList = new ArrayList<>();
            for(SensorPondEntity entity : sensorPondList){
                pondNameList.add(entity.getPondName());
            }
            String pondNames = "[" + String.join(",",pondNameList) + "]塘";
            name = name + pondNames;
        }
        String userId = AppSessionUtils.getUserId();
        String sensorId = sensorEntity.getId();
        SensorTypeSortEntity typeSort = this.querySensorTypeSort(companyId,userId,sensorId);
        List<Integer> sortList = null;
        if(null != typeSort){
            sortList = typeSort.toSort();
        }
        List<SensorDataListDTO> list = dataDTO.toList(sensorType);
        if(ObjectUtils.isNotEmpty(list) && ObjectUtils.isNotEmpty(sortList)){
            List<SensorDataListDTO> dataSortList = new ArrayList<>();
            Map<Integer,String> dataSortMap = new HashMap<>();
            for (Integer type : sortList){
                for (SensorDataListDTO dto : list){
                    if(null == type || null == dto.getType()){
                        continue;
                    }
                    if(type.equals(dto.getType())){
                        dataSortList.add(dto);
                        dataSortMap.put(type,"");
                        break;
                    }
                }
            }

            List<SensorDataListDTO> dataSortResultList = new ArrayList<>();
            dataSortResultList.addAll(dataSortList);
            for (SensorDataListDTO dto : list){
                if( !dataSortMap.containsKey(dto.getType())){
                    dataSortResultList.add(dto);
                }
            }
            list = dataSortResultList;
        }

        SensorDataListOutDTO outDTO = new SensorDataListOutDTO();
        outDTO.setSensorId(sensorId);
        outDTO.setTs(dataDTO.getTs());
        outDTO.setSn(sn);
        outDTO.setName(name);
        outDTO.setList(list);
        return BusinessDTO.sucessBusiness(outDTO,"传感器网关数据查询");
    }
    private BusinessDTO<SensorDataListOutDTO> querySensorDataDefault(){
        SensorDataListOutDTO outDTO = new SensorDataListOutDTO();
        outDTO.setSensorId("");
        outDTO.setTs("");
        outDTO.setSn("");
        outDTO.setName("");
        outDTO.setList(new ArrayList<>());
        return BusinessDTO.sucessBusiness(outDTO,"传感器网关数据查询");
    }

    /**
     * 传感器类型排序
     * @param webDTO
     * @return
     */
    public BusinessDTO<Object> sensorTypeSort(SensorTypeSortWebDTO webDTO){
        String companyId = AppSessionUtils.getCompanyId();
        String userId = AppSessionUtils.getUserId();
        String sensorId = webDTO.getSensorId();
        List<Integer> sort = webDTO.getSort();
        SensorTypeSortEntity typeSort = this.querySensorTypeSort(companyId,userId,sensorId);
        SensorTypeSortEntity entity = new SensorTypeSortEntity();
        if(null == typeSort){
            entity.setUserId(userId);
            entity.setSensorId(sensorId);
            entity.setCompanyId(companyId);
            entity.setSortJson(JSON.toJSONString(sort));
            sensorTypeSortMapper.insert(entity);
        }else {
            entity.setId(typeSort.getId());
            entity.setSortJson(JSON.toJSONString(sort));
            sensorTypeSortMapper.updateById(entity);
        }
        return BusinessDTO.sucessBusiness(new HashMap<>(),"传感器类型排序");
    }

    /**
     * 传感器类型查询
     * @param sensorId
     * @return
     */
    public BusinessDTO<Object> querySensorTypeList(String sensorId ){
        SensorEntity sensor = null;
        if(StringUtils.isNotEmpty(sensorId)){
            sensor = sensorMapper.selectById(sensorId);
        }else {
            String companyId = AppSessionUtils.getCompanyId();
            List<SensorEntity> sensorList = sensorMapper.selectList(new QueryWrapper<SensorEntity>().eq("company_id", companyId));
            if (ObjectUtils.isNotEmpty(sensorList)) {
                sensor = sensorList.get(0);
                for (SensorEntity entity : sensorList) {
                    if (entity.defaultSensor()) {
                        sensor = entity;
                        break;
                    }
                }
            }
        }
        if(null == sensor){
            return BusinessDTO.failBusiness(ErrorCodeUtils.DEVICE_NOT_INSTALL, ErrorCodeUtils.DEVICE_NOT_INSTALL_MSG);
        }
        sensor.setStatus(1);
        SensorDataDTO dataDTO = deviceDataMapper.querySensorData(sensor.getSn());
        if(null == dataDTO){
            sensor.setStatus(0);
        }
        List<Map<String,Object>> sensorTypeList = SensorTypeEnum.toTypeList(sensor.getId(),sensor.getType());
        Map<String,Object> map = new HashMap<>();
        map.put("sensor",sensor);
        map.put("sensorTypeList",sensorTypeList);
        return BusinessDTO.sucessBusiness(map,"传感器类型查询");
    }

    /**
     * 传减器数据统计
     * @param dto
     * @return
     */
    public BusinessDTO<SensorStatisticsOutDTO> querySensorStatistics(SensorStatisticsInDTO dto ){
        SensorEntity sensor = sensorMapper.selectById(dto.getSensorId());
        if(null == sensor){
            return BusinessDTO.failBusiness(ErrorCodeUtils.DEVICE_NOT_INSTALL, ErrorCodeUtils.DEVICE_NOT_INSTALL_MSG);
        }
        SensorTypeNormalEnum normalEnum = SensorTypeEnum.getNormalEnum(dto.getSensorType());
        if(null == normalEnum){
            return BusinessDTO.failBusiness("传感器类型[" + dto.getStatisticsType() + "]有误");
        }
        String companyId = AppSessionUtils.getCompanyId();
        DeviceNormalEntity normalEntity = deviceNormalMapper.selectOne(new QueryWrapper<DeviceNormalEntity>().eq("company_id",companyId).eq("type",normalEnum.getType()).last("LIMIT 1"));
        if(null == normalEntity){
            return BusinessDTO.failBusiness("传感器未配置正常值");
        }
        dto.setSn(sensor.getSn());
        dto.setFieldName(normalEnum.getFieldName());
        dto.checkStatisticsType();

        SensorStatisticsInfoDTO sensorInfo = SensorStatisticsInfoDTO.newDTO(sensor.getId(),sensor.getName(),normalEnum.getName(),normalEntity.getNormalMin(),normalEntity.getNormalMax());
        SensorStatisticsOutDTO outDTO = new SensorStatisticsOutDTO();
        outDTO.setSensorInfo(sensorInfo);
        outDTO.setStatisticsList(sensorMapper.querySensorStatistics(dto));
        return BusinessDTO.sucessBusiness(outDTO,"传减器数据统计");
    }

    /**
     * 传感器、塘口绑定
     * @param sensorId
     * @param pondId
     * @return
     */
    public BusinessDTO<Object> bindSensorPond(String sensorId,String pondId){
        String companyId = AppSessionUtils.getCompanyId();
        SensorEntity sensorEntity = sensorMapper.selectById(sensorId);
        if(null == sensorEntity ){
            return BusinessDTO.failBusiness("无此传感器");
        }else if( !companyId.equals(sensorEntity.getCompanyId())){
            return BusinessDTO.failBusiness("非公司传感器");
        }

        PondEntity pondEntity = pondManagerMapper.selectById(pondId);
        if(null == pondEntity){
            return BusinessDTO.failBusiness("无此塘口");
        }else if( !companyId.equals(pondEntity.getCompanyId())){
            return BusinessDTO.failBusiness("非公司塘口");
        }
        String sn = sensorEntity.getSn();
        List<SensorPondEntity> sensorPondList = this.querySensorPondList(companyId,sn);
        if(ObjectUtils.isNotEmpty(sensorPondList)){
            String id = sensorPondList.get(0).getId();
            SensorPondEntity updEntity = new SensorPondEntity();
            updEntity.setId(id);
            updEntity.setPondId(pondId);
            updEntity.setPondName(pondEntity.getName());
            updEntity.setUpdateTime(new Date());
            updEntity.setUpdateBy(AppSessionUtils.getUserName());
            sensorPondMapper.updateById(updEntity);
        }else {
            SensorPondEntity addEntity = new SensorPondEntity();
            addEntity.setCompanyId(companyId);
            addEntity.setPondId(pondId);
            addEntity.setPondName(pondEntity.getName());
            addEntity.setSn(sn);
            addEntity.setCreateBy(AppSessionUtils.getUserName());
            sensorPondMapper.insert(addEntity);
        }
        return BusinessDTO.sucessBusiness(new HashMap<>());
    }

    private SensorTypeSortEntity querySensorTypeSort(String companyId,String userId,String sensorId){
        QueryWrapper queryWrapper = new QueryWrapper<SensorTypeSortEntity>().eq("company_id",companyId).eq("user_id",userId).eq("sensor_id",sensorId);
        List<SensorTypeSortEntity> list = sensorTypeSortMapper.selectList(queryWrapper);
        if(ObjectUtils.isNotEmpty(list)){
            return list.get(0);
        }
        return null;
    }

    private List<SensorPondEntity> querySensorPondList(String companyId,String sn){
        return sensorPondMapper.selectList(new QueryWrapper<SensorPondEntity>().eq("company_id",companyId).eq("sn",sn));
    }

    private List<DeviceNormalEntity> queryNormalList(String companyId){
        return deviceNormalMapper.selectList(new QueryWrapper<DeviceNormalEntity>().eq("company_id",companyId));
    }

    private void initDeviceNormal(List<DeviceNormaTemplateEntity> templateEntities,String companyId){
        if(ObjectUtils.isEmpty(templateEntities)){
            return;
        }
        for(DeviceNormaTemplateEntity template : templateEntities){
            DeviceNormalEntity normalEntity = new DeviceNormalEntity();
            normalEntity.setNormalMax(template.getNormalMax());
            normalEntity.setNormalMin(template.getNormalMin());
            normalEntity.setCompanyId(companyId);
            normalEntity.setType(template.getType());
            normalEntity.setUnit(template.getUnit());
            normalEntity.setValueMax(template.getValueMax());
            normalEntity.setValueMin(template.getValueMin());
            try {
                deviceNormalMapper.insert(normalEntity);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

}
